using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace Mehat.San.SanFS
{

	public enum VirtualMountType
	{
		Invalid,
		Path,
		Device,
		MediaChanger
	}

	public abstract class VirtualMount : Mehat.San.SanFS.IVirtualMount
	{
		private string				mName;			// Name of this virtual mount
		private VirtualMountType	mType;			// Type of virtual mount
		private bool				mMerge;			// Merge colliding directories
		private string				mInternalRoot;	// Where this virtual mount is rooted internally
		private bool				mCache;			// Cache file-system entries

		internal VirtualMount()
		{
		}
		
		public VirtualMount(XmlNode	XmlConfig)
		{
			mName = XmlConfig.Attributes.GetNamedItem("Name").Value;
			mType = (VirtualMountType) Enum.Parse(typeof(VirtualMountType), XmlConfig.Attributes.GetNamedItem("Type").Value, true);
			mMerge = bool.Parse(XmlConfig.Attributes.GetNamedItem("Merge").Value);
			mInternalRoot = XmlConfig.Attributes.GetNamedItem("IntMountPt").Value;
			mCache = bool.Parse(XmlConfig.Attributes.GetNamedItem("Cache").Value);
		}

		public abstract IVirtualMount CreateInstance(XmlNode XmlConfig);
		protected abstract void Attach(IDirectory InternalRoot);
		
		public abstract void OpenFile(FileHandle Fh);
		public abstract long ReadFile(FileHandle Fh, byte[] Buffer, long Offset);
		public abstract void FlushFile(FileHandle Fh);
		public abstract void ReleaseFile(FileHandle Fh);
		public void Attach()
		{
			/*
			 * Create the VMount internal root mount point
			 */
			IDirectory intMntPt = DirEntFactory.CreateDirectories(this, mInternalRoot, mMerge);
			
			/*
			 * Call class specific attach
			 */
			Attach(intMntPt);	
		}

		public void Detach()
		{
			throw new NotImplementedException();
		}

		public string Name
		{
			get { return mName; }
		}

		public VirtualMountType Type
		{
			get { return mType; }
		}

		public bool Merge
		{
			get { return mMerge; }
		}
		
		public bool Cache
		{
			get { return mCache; }
		}

		public string InternalRoot
		{
			get { return mInternalRoot; }
		}
	}  // END CLASS
}  // END NAMESPACE
